<template>
  <AuModal
    v-model="showUploadPopup"
    :title="t('material.upload.title')"
    :padding="false"
    v-bind="$attrs"
    @handleConfirm="submit"
    @click="closePopup"
  >
    <div class="flex justify-center py-[30px] px-[20px]">
      <el-upload
        ref="uploadRef"
        v-model:file-list="fileList"
        class="upload-demo"
        :on-change="before"
        action=""
        multiple
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-exceed="handleExceed"
        :limit="1"
        accept="xlsx,xls"
        :auto-upload="false"
      >
        <el-button type="primary">{{ t("material.upload.button") }}</el-button>
        <template #tip>
          <div class="el-upload__tip">
            {{ t("material.upload.tip") }}
            <a href="#" style="color: blue" @click="fileDownload">{{
              t("material.upload.template_download")
            }}</a>
          </div>
        </template>
      </el-upload>
    </div>
    <AuModal
      v-model="showError"
      :padding="false"
      width="460px"
      :showCancel="false"
      @handleConfirm="
        () => {
          showError = false;
          errorList = [];
        }
      "
      @close="
        () => {
          errorList = [];
        }
      "
    >
      <template #title>
        <div class="flex items-center text-[14px]">
          <span class="text-[40px] text-[--el-color-danger]">
            <IconifyIconOnline icon="pepicons-pop:exclamation-circle-filled" />
          </span>
          &emsp;{{ t("material.upload.error") }}
        </div>
      </template>
      <template #default>
        <el-scrollbar height="50vh">
          <div
            v-for="(item, i) in errorList"
            :key="i"
            class="first:mt-[20px] mt-[10px] px-[20px] last:mb-[10px]"
          >
            <div class="text-[14px] text-[--autata-font-gray-color] mb-[4px]">
              {{ t("material.upload.error_reason", { index: i + 1 }) }}
            </div>
            <component :is="item" class="text-[--autata-font-color]]" />
          </div>
        </el-scrollbar>
      </template>
    </AuModal>
  </AuModal>
</template>

<script setup lang="ts">
import { AuModal } from "@/components/AuModal";
import {
  getCurrentInstance,
  computed,
  ref,
  h,
  onMounted,
  onUnmounted,
  watch
} from "vue";
import { getGroupList, addList } from "@/api/teaInfuser/store";
import { addStoreGroup, GroupProp } from "@/api/teaInfuser/store";
import * as xlsx from "xlsx";

import {
  genFileId,
  UploadProps,
  UploadRawFile,
  UploadUserFile
} from "element-plus";
import { ElMessage, ElLoading, ElMessageBox } from "element-plus";
import {
  getMaterialTypeList,
  materialAdd,
  materialExportAdd,
  materialTypeAdd
} from "@/api/cabinet/material";
import { getMaterialList } from "@/api/cabinet/formula";
import { useI18n } from "vue-i18n";

const { t } = useI18n();
const { proxy } = getCurrentInstance();

const errorList = ref([]);
const showError = ref(false);

const uploadRef = ref(null);
onMounted(() => {
  console.log("已加载");
  fileList.value = [];
  getMatList();
  getTypeSelectList();
  //storeDataList.value = null;
});

onUnmounted(() => {
  console.log("组件已卸载");
  fileList.value = [];
  storeDataList.value = null;
  // 执行清理操作
});

const fileDownload = e => {
  e.preventDefault();
  const path = import.meta.env?.VITE_PUBLIC_PATH ?? "/admin/";
  // 使用 window.location.href 直接下载文件
  window.location.href = location.origin + path + "/物料管理.xlsx";
};

const matIdList = ref<any[]>([]);
const matNameList = ref<any[]>([]);
const getMatList = async () => {
  const res = await getMaterialList({
    start_page: 1,
    size: 0
  });
  matIdList.value = res.data.map(item => item.material_id);
  matNameList.value = res.data.map(item => item.name);
};
const typeList = ref<any[]>([]);
const getTypeSelectList = async () => {
  const res = await getMaterialTypeList({
    start_page: 1,
    size: 0
  });
  typeList.value = res.data;
};

// 查找函数
const findObjectByProperty = (
  propertyName: string,
  value: string,
  parentId: number
) => {
  return typeList.value.find(
    obj => obj[propertyName] === value && obj.parent_id === parentId
  );
};

const storeDataList = ref();

const fileList = ref<UploadUserFile[]>([]);
const handlePreview: UploadProps["onPreview"] = uploadFile => {
  //console.log(uploadFile);
};

const handleRemove: UploadProps["onRemove"] = (file, fileLists) => {
  fileList.value = [];
  uploadRef.value?.clearFiles();
};

const handleExceed: UploadProps["onExceed"] = files => {
  uploadRef.value!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  uploadRef.value!.handleStart(file);
};
/**
 * 把文件按照二进制进行读取
 * @param file
 * @returns
 */
const readFile = (file: File) => {
  return new Promise(resolve => {
    let reader = new FileReader();
    reader.readAsBinaryString(file);
    reader.onload = ev => {
      resolve(ev.target?.result);
    };
    console.log(reader);
  });
};

/**
 * 处理文件上传前的Excel文件解析操作
 * @param {any} file - 上传的文件对象（通常为ElUpload组件的上传文件对象）
 * @returns {void} 无返回值
 */
const before = (file: any) => {
  // 初始化文件读取器以处理上传的Excel文件
  const reader = new FileReader();

  // 文件读取完成后的回调函数，负责解析Excel文件内容
  reader.onload = e => {
    // 获取文件读取结果数据
    const data = e.target.result;

    // 解析Excel文件并提取第一个工作表的数据
    const workbook = xlsx.read(data, { type: "array" });
    const firstSheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[firstSheetName];

    // 将工作表数据转换为JSON格式并更新到响应式数据中
    storeDataList.value = xlsx.utils.sheet_to_json(worksheet);
    // storeDataList.value = results;

    // 显示上传成功的提示信息
    ElMessage({
      message: t("material.upload.message.upload_success"),
      type: "success"
    });
  };

  // 开始以ArrayBuffer格式读取文件内容
  reader.readAsArrayBuffer(file.raw);
};

interface Props {
  modelValue: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false
});

const emit = defineEmits(["update:modelValue", "handleConfirm"]);

const showUploadPopup = computed({
  get() {
    return props.modelValue;
  },
  set(val: boolean) {
    emit("update:modelValue", val);
  }
});

const uploadTitle = ref("导入物料");

// 辅助函数：校验不为空
const check = async (storeList: any[]) => {
  const msgList = [];

  const duplicates = [];
  const duplicatesName = [];
  let i = 1;
  for (const item of storeList) {
    const numReg = /^[A-Za-z0-9_-]+$/;
    if (!item.material_id || item.material_id == "") {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.material_id_empty", { index: i })
          )
        ])
      );
    } else if (!numReg.test(item.material_id)) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.material_id_number", {
              index: i,
              id: item.material_id
            })
          )
        ])
      );
    } else if (item.material_id.length > 20) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.material_id_length", {
              index: i,
              id: item.material_id
            })
          )
        ])
      );
    } else if (matIdList.value.includes(item.material_id)) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.material_id_exists", {
              index: i,
              id: item.material_id
            })
          )
        ])
      );
    }

    if (duplicates.includes(item.material_id)) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.material_id_duplicate", {
              index: i,
              id: item.material_id
            })
          )
        ])
      );
    } else {
      duplicates.push(item.material_id);
    }

    if (!item.name || item.name?.trim() == "") {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.name_empty", { index: i })
          )
        ])
      );
    } else if (item.name.length > 20) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.name_length", {
              index: i,
              name: item.name
            })
          )
        ])
      );
    } else if (matNameList.value.includes(item.name)) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.name_exists", {
              index: i,
              name: item.name
            })
          )
        ])
      );
    }

    if (duplicatesName.includes(item.name)) {
      msgList.push(
        h("p", { style: "line-height: 2; font-size: 14px" }, [
          h(
            "span",
            null,
            t("material.upload.validation.name_duplicate", {
              index: i,
              name: item.name
            })
          )
        ])
      );
    } else {
      duplicatesName.push(item.name);
    }

    if (item.spec) {
      const formatRegex = /^([^-,]+?-[^-,]+?)(,[^-,]+?-[^-,]+?)*$/;
      if (!formatRegex.test(item.spec)) {
        msgList.push(
          h("p", { style: "line-height: 2; font-size: 14px" }, [
            h(
              "span",
              null,
              t("material.upload.validation.spec_format", { index: i })
            )
          ])
        );
      }
    }

    if (item.publish_status) {
      if (item.publish_status != "上架" && item.publish_status != "下架") {
        msgList.push(
          h("p", { style: "line-height: 2; font-size: 14px" }, [
            h(
              "span",
              null,
              t("material.upload.validation.status_invalid", { index: i })
            )
          ])
        );
      }
    }

    if (item.use_barcode) {
      if (item.use_barcode != "是" && item.use_barcode != "否") {
        msgList.push(
          h("p", { style: "line-height: 2; font-size: 14px" }, [
            h(
              "span",
              null,
              t("material.upload.validation.barcode_invalid", { index: i })
            )
          ])
        );
      }
    }

    if (item.device_type) {
      const regex = /^(茶粉机|柜式机)(,(茶粉机|柜式机))?$/;
      if (!regex.test(item.device_type)) {
        msgList.push(
          h("p", { style: "line-height: 2; font-size: 14px" }, [
            h(
              "span",
              null,
              t("material.upload.validation.device_type_invalid", { index: i })
            )
          ])
        );
      }
    }

    i++;
  }

  return msgList;
};

const handleData = (data: any[]) => {
  if (data.length > 0) {
    //   物料编码	物料名称	物料类型	状态	设备类型	规格	使用条形码	条形码	备注
    const matchData = {
      物料编码: "material_id",
      物料名称: "name",
      规格: "spec",
      使用条形码: "use_barcode",
      条形码: "barcode",
      备注: "note",
      设备类型: "device_type",
      状态: "publish_status",
      物料类型: "type_id"
    };
    const selfData = [];
    for (const item of data) {
      let curObj = {};
      for (const key in matchData) {
        if (item[key] != undefined) {
          curObj[matchData[key]] = item[key];
        }
      }
      selfData.push(curObj);
    }
    return selfData;
  }
};

const handleToPushData = async (data: any[]) => {
  let newData = [];
  for (const v of data) {
    const newSpec = v.spec
      ? v.spec.split(",").map(pair => {
          const [name, value] = pair.split("-").map(s => s.trim());

          // 完整性校验
          if (!name || !value) {
            throw new Error(`存在空字段的组合：${pair}`);
          }

          return { name, value };
        })
      : [];
    v.spec = JSON.stringify(newSpec);

    if (v.type_id) {
      const find = typeList.value.find(item => item.name == v.type_id);
      if (find) {
        v.type_id = find.id;
      } else {
        const addRes = await materialTypeAdd({
          name: v.type_id,
          note: ""
        });
        if (addRes.code == 200) {
          v.type_id = addRes.data.id;
          typeList.value.push(addRes.data);
          // await getTypeSelectList();
        }
      }
    }

    v.publish_status = v.publish_status == "下架" ? 0 : 1;
    v.use_barcode = v.use_barcode == "是";
    // 固定的参数
    v.amount_unit = "g"; //标准量单位
    const material_config = {};
    v.forced_clean = false;
    material_config["forced_clean"] = v.forced_clean;
    v.material_config = JSON.stringify(material_config);
    newData.push(v);
  }
  return newData;
};

const submit = async (data: any) => {
  //emit("submit", data);
  if (storeDataList.value == undefined) {
    ElMessage({
      message: t("material.upload.message.no_file"),
      type: "error"
    });
  }

  let storeList = [];
  const hasHandleData = handleData(storeDataList.value);

  //校验
  let errList = [];

  const checkRes = await check(hasHandleData);
  if (checkRes.length) {
    errList.push(...checkRes);
  }

  if (errList.length > 0) {
    showError.value = true;
    errorList.value = errList;
    uploadRef.value.clearFiles();
    return;
  }

  storeList = await handleToPushData(hasHandleData);

  const loading = ElLoading.service({
    lock: true,
    text: t("material.upload.message.loading"),
    background: "rgba(0, 0, 0, 0.7)"
  });

  /* const addListParam = {
    storeParams: storeList
  }; */
  errorList.value = [];
  try {
    for (const item of storeList) {
      const res = await materialExportAdd(item);
      if (res.code != 200) {
        errorList.value.push(h("p", {}, res.message));
      }
    }
  } catch (error) {}
  loading.close();
  if (errorList.value.length) {
    uploadRef.value.clearFiles();
    storeDataList.value = null;
    fileList.value = [];
    showError.value = true;
  } else {
    uploadRef.value.clearFiles();
    ElMessage({
      message: t("material.upload.message.import_success"),
      type: "success"
    });
    showError.value = false;
    emit("update:modelValue", false);
    emit("handleConfirm");
  }
};
const closePopup = () => {
  console.log("关闭");
};

const closeErrorDialog = () => {
  showError.value = false;
  errorList.value = [];
};

watch(
  () => props.modelValue,
  (newValue, oldValue) => {
    if (newValue) {
      // 弹窗打开时，清空错误信息
      fileList.value = [];
      errorList.value = [];
      showError.value = false;
      getMatList();
      getTypeSelectList();
    }
  }
);
</script>
